package pl.com.hme.kody.pocztowe.asynctask;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;

import pl.com.hme.kody.pocztowe.R;
import pl.com.hme.kody.pocztowe.data.SearchResults;
import pl.com.hme.kody.pocztowe.exception.ParserException;
import pl.com.hme.kody.pocztowe.http.HttpClientFactory;
import pl.com.hme.kody.pocztowe.parser.PnaJsonParser;
import pl.com.hme.kody.pocztowe.util.JsonUtils;
import pl.com.hme.kody.pocztowe.util.WeakAsyncTask;
import android.content.Context;
import android.provider.Settings;
import android.util.Log;

public class PnaAsyncTask extends WeakAsyncTask<String, String, Void, PnaCodeResultCallback> {

	private static final String TAG = "PnaAsyncTask";
	private String mPrefixGetLine = "http://infomap.pl/REST/pna.php?method=get_postal_code_of_place_street_community_id&place=";
	private String mStreetGetLine = "&street=";
	private String mIdGetLine = "&community_id=0&unique_id=";

	private ParserException mException;

	private HttpClient mHttpClient;

	private Context mContext;

	public PnaAsyncTask(Context context, PnaCodeResultCallback target) {
		super(target);

		mContext = context;
		mHttpClient = HttpClientFactory.getHttpClient(null);
	}

	@Override
	protected Void doInBackground(PnaCodeResultCallback target, String... params) {
		String androidID = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.ANDROID_ID);
		String uri = null;
		try {
			uri = mPrefixGetLine
					+ URLEncoder.encode(params[0].substring(0, 1).toUpperCase() + params[0].substring(1), "UTF-8")
					+ mStreetGetLine
					+ URLEncoder.encode(params[1].substring(0, 1).toUpperCase() + params[1].substring(1), "UTF-8")
					+ mIdGetLine + androidID;
		} catch (UnsupportedEncodingException e) {
			mException = new ParserException("Bad input data encoding", e);
			return null;
		}
		
		try {
			target.receiveResults(execute(new HttpGet((uri))));
		} catch (ParserException e) {
			mException = e;
		}

		return null;
	}

	private SearchResults execute(HttpUriRequest request) throws ParserException {
		InputStream input = null;

		publishProgress(mContext.getString(R.string.wait_connecting_server));
		try {

			try {
				HttpResponse resp = mHttpClient.execute(request);
				int status = resp.getStatusLine().getStatusCode();
				if (status != HttpStatus.SC_OK) {
					throw new ParserException(mContext.getString(R.string.error_http_response));
				}
				input = resp.getEntity().getContent();
			} catch (Exception e) {
				throw new ParserException(mContext.getString(R.string.error_connection), e);
			}

			publishProgress(mContext.getString(R.string.wait_parsing_xml));
			return PnaJsonParser.parseJsonString(mContext, JsonUtils.convertInputStreamToString(input));
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
					Log.w(TAG, "Can't close InputStream", e);
				}
			}
		}
	}

	@Override
	protected void onProgressUpdate(String... values) {
		super.onProgressUpdate(values);
		getTarget().publishProgress(values[0]);
	}

	@Override
	protected void onPostExecute(PnaCodeResultCallback target, Void result) {
		super.onPostExecute(target, result);

		if (mException != null) {
			target.reportError(mException);
		}
	}

}
